package com.zhihu.service.impl;

import com.zhihu.Enums.AutherAndForward;
import com.zhihu.dao.*;
import com.zhihu.pojo.*;
import com.zhihu.pojo.baseVo.BaseResult;
import com.zhihu.pojo.req.SolrSearchQues;
import com.zhihu.pojo.req.TypeReq;
import com.zhihu.pojo.req.VideoReq;
import com.zhihu.service.VideoService;
import com.zhihu.utils.GetVideoInfo;
import com.zhihu.utils.RedisKeyUtils;
import com.zhihu.utils.UploadUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

@Service
public class VideoServiceImpl implements VideoService {

    @Autowired
    VideoMapper videoMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    HttpSolrClient httpSolrClient;
    @Autowired
    VideoRepository videoRepository;
    @Autowired
    QuestionRepository questionRepository;
    @Autowired
    TypeTempRepository typeTempRepository;
    @Autowired
    LikeOpusRepository likeOpusRepository;

    /**
     * 上传视频，获取视频的时长、大小以及视频的准备插图，存入redis，等待进一步操作
     * @param multipartFile,user 上传视频,用户信息
     * @return baseResult   返回上传结果
     */
    @Override
    public BaseResult upLoadVideo(MultipartFile multipartFile, User user) {

        //上传的工具类
        UploadUtils uploadUtils = new UploadUtils();
        //视频处理的工具类
        GetVideoInfo getVideoInfo = new GetVideoInfo();
        //准备存储在redis中的工具类
        VideoReq videoReq = new VideoReq();

        try {
            //1、用户ip
            videoReq.setUserId(user.getUserId());
            //2、用户头像
            videoReq.setViUserImg(user.getImg());
            //3、用户昵称
            videoReq.setViUserName(user.getUserName());
            //4、作品类型
            videoReq.setOpusTap(3);

            //1. 上传的视频路径
            String uploadVideoUrl = uploadUtils.upload(multipartFile);
            //5、上传后视频路径
            videoReq.setViUrl(uploadVideoUrl);
            //6、获取视频时长
            Date videoTime = getVideoInfo.getVideoTime(multipartFile);
            videoReq.setViLength(videoTime);
            //7、获取视频的大小
            String videoSize = getVideoInfo.ReadVideoSize(multipartFile);
            videoReq.setViSize(videoSize);

            //生成唯一的二级key
            UUID uuid = UUID.randomUUID();
            String u = uuid.toString();
            String videoPath=uploadVideoUrl+u;
            videoReq.setVideoPath(videoPath);

            //8、准备封面图片
            //本地生成的封面图片，待上传
            //调用工具类截取9张图放在数组里，上传到七牛云上,获得上传后的9张封面图的数组
            String []videoImg = getVideoInfo.getVideoImg(uploadVideoUrl);
            for(int i=0; i<9;i++){
                String imagePath = videoImg[i];
                FileItem fileItem = createFileItem(imagePath);
                MultipartFile multipartImg = new CommonsMultipartFile(fileItem);
                //上传后的地址
                String uploadImgUrl = uploadUtils.upload(multipartImg);
                videoImg[i]=uploadImgUrl;
                //获取视频文件名
                String itemName = fileItem.getName();
                videoReq.setViTitle(itemName);
            }
            videoReq.setViImages(videoImg);
            //视频上传后默认给第一帧作为封面，不满意可以更换
            videoReq.setViImg(videoImg[1]);
            //redis:    获取hashmap
            HashOperations hashOperations = redisTemplate.opsForHash();
            //redis:    设置第一、二层key
            //Object o = hashOperations.get(user.getUserId(), videoPath);
            hashOperations.put(user.getUserId(), videoPath,videoReq);
            //存将key存在redis中

            return new BaseResult(1,"上传成功！",videoReq);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new BaseResult(0,"上传失败！");
    }
    
    /**
     * 根据用户的登录信息，去草稿箱（redis）拿到上传的视频集合信息
     * 使用redisTemplate.opsForHash().scan拿到二层key和value的集合
     * @return 用户的上传的视频集合信息
     */
    @Override
    public BaseResult findVideosInRedis(User user) {
        //判断redis里是否有视频
        Boolean aBoolean = redisTemplate.hasKey(user.getUserId());
        if(aBoolean){
            Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(user.getUserId(), ScanOptions.NONE);
            ArrayList<VideoReq> videoReqArrayList = new ArrayList<>();
            if(cursor!=null && !cursor.hasNext()){
                Map.Entry<Object, Object> entry = cursor.next();
                String key = (String)entry.getKey();
                VideoReq videoReq = (VideoReq) entry.setValue(key);
                videoReqArrayList.add(videoReq);
            }
            return new BaseResult(1,"查询成功！",videoReqArrayList);
        }
        return new BaseResult(0,"您还没有上传视频！");
    }

    /**
     * 根据用户的登录信息，去草稿箱（redis）删除上传的视频集合信息
     * @param videoPath  二层key
     * @return 删除信息结果集
             */
    @Override
    public BaseResult delVideoInRedis(User user, String videoPath) {
        //1、拿到redis代理类，查询想要的视频信息
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), videoPath);
        if(aBoolean) {
           redisTemplate.opsForHash().delete(user.getUserId(), videoPath);
            VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
            if(videoReq==null){
                return new BaseResult(1,"删除成功！");
            }
        }
        return new BaseResult(0,"删除失败！");
    }

    /**
     * redis中查找视频的详细信息
     * @param videoPath 上传的视频路径
     * @param user 用户的登录信息
     * @return 该视频的信息
     */
    @Override
    public BaseResult findOneInRedis(User user, String videoPath) {

        //1、拿到redis代理类，查询想要的视频信息
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), videoPath);
        if(aBoolean) {
            VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
            if(videoReq!=null){
                return new BaseResult(1,"查询成功！",videoReq);
            }
        }
        return new BaseResult(0,"查询失败！");
    }

    /**
     * 上传图片作为封面
     * @param multipartFile 封面照片文件
     * @param videoPath 对应上传的视频的路径
     * @return 上传成功后的回显，以及结果集
     */
    @Override
    public BaseResult upLoadVideoImg(User user, String videoPath, MultipartFile multipartFile) {

        //创建上传文件的工具类
        UploadUtils uploadUtils = new UploadUtils();
        //上传完照片拿到云端的地址
        String uploadUrl = uploadUtils.upload(multipartFile);
        //通过redisTemplate模板类在redis里面查找是否有用户的待上传视频
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), videoPath);
        if(aBoolean){
            VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
            videoReq.setViImg(uploadUrl);
            redisTemplate.opsForHash().put(user.getUserId(), videoPath,videoReq);
            return new BaseResult(1,"上传成功！");
        }
        return new BaseResult(0,"上传封面照片失败！");
    }

    /**
     * 选择现成帧图作为封面
     * @param videoImg 封面照片帧图
     * @param videoPath 对应上传的视频的路径
     * @return 上传成功后的回显，以及结果集
     */
    @Override
    public BaseResult chooseVideoImg(User user, String videoImg, String videoPath) {

        //通过redisTemplate模板类在redis里面查找是否有用户的待上传视频
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), videoPath);
        if(aBoolean){
            VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
            videoReq.setViImg(videoImg);
            redisTemplate.opsForHash().put(user.getUserId(), videoPath,videoReq);
            return new BaseResult(1,"上传成功！");
        }
        return new BaseResult(0,"上传封面照片失败！");
    }

    /**
     * 使用solr实现问题的搜索展示
     * @param key    问题关键字
     * @param page 当前页数
     * @param size   分页
     * @return 包含关键字的结果集
     */
    @Override
    public BaseResult findBySolrSearchQues(String key, Integer page, Integer size) {

        //创建一个solrQuery对象
        SolrQuery solrQuery = new SolrQuery();
        BaseResult baseResult = new BaseResult();
        ArrayList<Question> list = new ArrayList<Question>();
        //设置查询条件
        solrQuery.setQuery(key);

        //设置分页条件
        solrQuery.setStart((page - 1) * size);
        solrQuery.setRows(size);

        //设置默认搜索域
        solrQuery.set("df", "ques_keywords");

        //开启高亮显示
        solrQuery.setHighlight(true);
        //设置高亮显示的域
        solrQuery.addHighlightField("ques_title");
        solrQuery.addHighlightField("ques_info");

        //设置更喜欢的字段
//        solrQuery.addMoreLikeThisField("ques_title");
        //设置高亮标签前缀
        //solrQuery.setHighlightSimplePre("<font style=\"color=red\">");
        solrQuery.setHighlightSimplePre("<font style='color:red'>");
        //设置高亮标签后缀
        solrQuery.setHighlightSimplePost("</font>");

        try {
            //根据query查询索引库
            QueryResponse queryResponse = httpSolrClient.query(solrQuery);

            if (queryResponse != null) {
                //得到高亮数据
                Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
                if (highlighting != null && highlighting.size() > 0) {

                    //取查询结果
                    SolrDocumentList solrDocumentList = queryResponse.getResults();
                    if (solrDocumentList != null) {
                        //取查询结果总记录数
                        long numFound = solrDocumentList.getNumFound();
                        baseResult.setCount(numFound);
                        List<SolrSearchQues> beans = queryResponse.getBeans(SolrSearchQues.class);

                        if (beans != null && beans.size() > 0) {

                                for (SolrSearchQues solrSearchQues : beans) {
                                    //获取高亮的问题对象
                                    Map<String, List<String>> stringListMap = highlighting.get(solrSearchQues.getQuestionId());

                                    //标题和内容中同时存在关键字
                                    String quesTitle1 = stringListMap.get("ques_title").get(0);
                                    String quesInfo1 = stringListMap.get("ques_info").get(0);

                                    if(quesTitle1 !=null && !quesTitle1.equals("")){
                                        solrSearchQues.setQuesTitle(quesTitle1);
                                    }
                                    if(quesInfo1 !=null && !quesInfo1.equals("")){
                                        solrSearchQues.setQuesInfo(quesInfo1);
                                    }

                                    //将solrSearchQues中的参数放入新集合中
                                    //在高并发高流量的网站使用Int或许不够，应该使用Long
                                    int questionId = Integer.parseInt(solrSearchQues.getQuestionId());
                                    int quesCommNums = Integer.parseInt(solrSearchQues.getQuesCommNums().toString());
                                    int quesLikeNum = Integer.parseInt(solrSearchQues.getQuesLikenum().toString());

                                    Question question = new Question();
                                    question.setQuestionId(questionId);
                                    question.setQuesCommNums(quesCommNums);
                                    question.setQuesLikeNum(quesLikeNum);
                                    question.setQuesInfo(solrSearchQues.getQuesInfo());
                                    question.setQuesTitle(solrSearchQues.getQuesTitle());
                                    question.setQuesImg(solrSearchQues.getQuesImg());
                                    question.setOpusTap(solrSearchQues.getOpusTap());
                                    question.setQuesCreatetime(solrSearchQues.getQuesCreatetime());
                                    question.setQuesVio(solrSearchQues.getQuesVio());
                                    question.setQuesUserImg(solrSearchQues.getQuesUserimg());
                                    question.setQuesUserName(solrSearchQues.getQuesUsername());
                                    question.setUserId(solrSearchQues.getUserId());

                                    list.add(question);
                                    System.out.println(list.toString());
                               }
                            baseResult.setData(list);
                        }
                    }
                }
            }
            baseResult.setCode(1);
            baseResult.setMsg("查询成功！");
            return baseResult;
        } catch(Exception e){
            e.printStackTrace();
        }
        baseResult.setCode(0);
        baseResult.setMsg("查询失败！");
        return baseResult;
    }

    /**
     * 选择问题
     * @param questionId solr里的问题id
     * @return 封装好的结果集
     */
    @Override
    public BaseResult chooseSearchQuestion( Integer questionId) {

        //获取实时评论数
        String secondKey = RedisKeyUtils.getPublishedOpusKey("3", questionId.toString());
        String firstKey = RedisKeyUtils.MAP_OPUS_KEY;
        Integer quesCommNums = Integer.valueOf(redisTemplate.opsForHash().get(firstKey, secondKey).toString());

        //创建新的solr查询对象
        SolrQuery solrQuery = new SolrQuery();
        //修改搜索域
        solrQuery.setParam("df","id");
        //添加待搜索值
        solrQuery.setQuery(questionId.toString());
        try {
            //获得搜索结果
            QueryResponse queryResponse = httpSolrClient.query(solrQuery);
            if(queryResponse==null){
                return new BaseResult(0,"搜索结果为空！");
            }
            //获得搜索问题结果集
            List<SolrSearchQues> solrSearchQuesList = queryResponse.getBeans(SolrSearchQues.class);
            if(solrSearchQuesList!=null && solrSearchQuesList.size()>0){
                //获得搜索问题对象
                SolrSearchQues solrSearchQues = solrSearchQuesList.get(0);

                int quesLikeNum = Integer.parseInt(solrSearchQues.getQuesLikenum().toString());

                Question question = new Question();
                question.setQuestionId(questionId);
                question.setQuesTitle(solrSearchQues.getQuesTitle());
                question.setUserId(solrSearchQues.getUserId());
                question.setQuesCommNums(quesCommNums);
                question.setQuesLikeNum(quesLikeNum);
                question.setQuesInfo(solrSearchQues.getQuesInfo());
                question.setQuesImg(solrSearchQues.getQuesImg());
                question.setOpusTap(solrSearchQues.getOpusTap());
                question.setQuesCreatetime(solrSearchQues.getQuesCreatetime());
                question.setQuesVio(solrSearchQues.getQuesVio());
                question.setQuesUserImg(solrSearchQues.getQuesUserimg());
                question.setQuesUserName(solrSearchQues.getQuesUsername());
                question.setUserId(solrSearchQues.getUserId());
                return new BaseResult(1,"查询成功！",question);
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new BaseResult(0,"查询失败！");
    }

    /**
     * 将问题和描述插入草稿箱
     * @param videoPath redis里的二级key
     * @param quesInfo 问题的描述
     * @return 封装好的结果集
     */
    @Override
    public BaseResult insertSearchQuestion(User user, String quesTitle, String quesInfo, String videoPath) {

        //通过redisTemplate模板类在redis里面查找是否有用户的待上传视频
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), videoPath);
        if(aBoolean){
            VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
            videoReq.setQuesTitle(quesTitle);
            if(quesInfo!=null && quesInfo!=""){
                videoReq.setQuesInfo(quesInfo);
            }
            redisTemplate.opsForHash().put(user.getUserId(), videoPath,videoReq);
            return new BaseResult(1,"添加问题和问题描述成功！");
        }
        return new BaseResult(0,"添加问题和问题描述失败！");
    }

    /**
     * 使用solr实现话题的标签展示
     * @param key   标签关键字
     * @param page  当前页数
     * @param size  分页
     * @return
     */
    @Override
    public BaseResult findTypeByTypeReq(String key, Integer page, Integer size) {
        //创建一个solrQuery对象
        SolrQuery solrQuery = new SolrQuery();
        BaseResult baseResult = new BaseResult();
        ArrayList<Type> list = new ArrayList<Type>();
        //设置查询条件
        solrQuery.setQuery(key);

        //设置分页条件
        solrQuery.setStart((page - 1) * size);
        solrQuery.setRows(size);

        //设置默认搜索域
        solrQuery.set("df", "type_name");

        //开启高亮显示
        solrQuery.setHighlight(true);
        //设置高亮显示的域
        solrQuery.addHighlightField("type_name");

        //设置高亮标签前缀
        solrQuery.setHighlightSimplePre("<font style='color:red'>");
        //设置高亮标签后缀
        solrQuery.setHighlightSimplePost("</font>");

        try {
            //根据query查询索引库
            QueryResponse queryResponse = httpSolrClient.query(solrQuery);

            if (queryResponse != null) {
                //得到高亮数据
                Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
                if (highlighting != null && highlighting.size() > 0) {

                    //取查询结果
                    SolrDocumentList solrDocumentList = queryResponse.getResults();
                    if (solrDocumentList != null) {
                        //取查询结果总记录数
                        long numFound = solrDocumentList.getNumFound();
                        baseResult.setCount(numFound);
                        List<TypeReq> beans = queryResponse.getBeans(TypeReq.class);

                        if (beans != null && beans.size() > 0) {

                            for (TypeReq typeReq : beans) {
                                //获取高亮的问题对象
                                Map<String, List<String>> stringListMap = highlighting.get(typeReq.getTypeId());

                                //标题和内容中同时存在关键字
                                String typeId = stringListMap.get("id").get(0);
                                String typeName = stringListMap.get("type_name").get(0);

                                if(typeId !=null && !typeId.equals("")){
                                    typeReq.setTypeId(typeId);
                                }
                                if(typeName !=null && !typeName.equals("")){
                                    typeReq.setTypeName(typeName);
                                }

                                //将type中的参数放入新集合中
                                int typeId1 = Integer.parseInt(typeReq.getTypeId());

                                Type type = new Type();
                                type.setTypeId(typeId1);
                                type.setTypeName(typeName);

                                list.add(type);
                            }
                            baseResult.setData(list);
                        }
                    }
                }
            }
            baseResult.setCode(1);
            baseResult.setMsg("查询成功！");
            return baseResult;
        } catch(Exception e){
            e.printStackTrace();
        }
        baseResult.setCode(0);
        baseResult.setMsg("查询失败！");
        return baseResult;
    }

    /**
     * 绑定话题——添加视频和问题的标签
     * @param videoPath redis里的二级key
     * @param typeId 插入的标签的id
     * @return 封装好的结果集
     */
    @Override
    public BaseResult insertSearchType(User user,  String videoPath, Integer typeId) {

        HashOperations hashOperations = redisTemplate.opsForHash();

        Type type = new Type();
        type.setTypeId(typeId);

        //创建一个solrQuery对象
        SolrQuery solrQuery = new SolrQuery();
        //设置查询条件
        solrQuery.setQuery(typeId.toString());

        //设置默认搜索域
        solrQuery.set("df", "id");

            //根据query查询索引库
        QueryResponse queryResponse = null;
        try {
            queryResponse = httpSolrClient.query(solrQuery);
            if (queryResponse != null) {
                List<TypeReq> beans = queryResponse.getBeans(TypeReq.class);

                if (beans != null && beans.size() > 0) {

                    //标题和内容中同时存在关键字
                    TypeReq typeReq = beans.get(0);

                    //将type中的参数放入新集合中
                    int typeId1 = Integer.parseInt(typeReq.getTypeId());

                    type.setTypeId(typeId1);
                    type.setTypeName(typeReq.getTypeName());

                    VideoReq videoReq = (VideoReq) hashOperations.get(user.getUserId(), videoPath);
                    List<Type> typesList = videoReq.getTypesList();
                    if(typesList ==null){
                        ArrayList<Type> typeArrayList = new ArrayList<>();
                        videoReq.setTypesList(typeArrayList);
                    }
                    videoReq.getTypesList().add(type);
                    hashOperations.put(user.getUserId(), videoPath,videoReq);
                    return new BaseResult(1,"新增成功！");
                }
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new BaseResult(0,"添加失败！");
    }

    /**
     * 查看选择好的视频的标签
     * @param videoPath redis里的二级key
     * @return 封装好的结果集
     */
    @Override
    public BaseResult findTypeByRedis(User user, String videoPath) {

        VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
        if(videoReq!=null && videoReq.getTypesList().size()>0){
            return new BaseResult(1,"查询成功！",videoReq.getTypesList());
        }
        return new BaseResult(0,"查询失败！");
    }

    /**
     * 删除选择好的视频的标签
     * @param videoPath redis里的二级key
     * @return 封装好的结果集
     */
    @Override
    public BaseResult delTypeByRedis(User user, String videoPath, Integer typeId) {

        VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
        if(videoReq!=null && videoReq.getTypesList().size()>0){
            Iterator<Type> iterator = videoReq.getTypesList().iterator();
            if(iterator.hasNext()){
                Type type = iterator.next();
                if( (type.getTypeId().toString()).equals(typeId.toString()) ){
                    videoReq.getTypesList().remove(type);
                }
            }
            return new BaseResult(1,"删除标签成功！");
        }
        return new BaseResult(0,"删除标签失败！");
    }

    /**
     * 修改标题
     * @param videoPath redis里的二级key
     * @param viTitle 修改后的标题
     * @return 封装好的结果集
     */
    @Override
    public BaseResult updateNewTitle(User user, String videoPath, String viTitle) {

        VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
        if(videoReq!=null){
            videoReq.setViTitle(viTitle);
            redisTemplate.opsForHash().put(user.getUserId(), videoPath,videoReq);
            return new BaseResult(1,"修改成功！");
        }
        return new BaseResult(0,"修改失败！");
    }

    /**
     * 修改标题
     * @param videoPath redis里的二级key
     * @param viInfo 修改后的内容详情
     * @return 封装好的结果集
     */
    @Override
    public BaseResult updateNewInfo(User user, String videoPath, String viInfo) {
        VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
        if(videoReq!=null){
            videoReq.setViInfo(viInfo);
            redisTemplate.opsForHash().put(user.getUserId(), videoPath,videoReq);
            return new BaseResult(1,"修改成功！");
        }
        return new BaseResult(0,"修改失败！");
    }

    /**
     * 修改标题
     * @param videoPath redis里的二级key
     * @param autherAndForward 原创还是转发
     * @return 封装好的结果集
     */
    @Override
    public BaseResult updateAutherAndForward(User user, String videoPath, Integer autherAndForward) {
       if(autherAndForward!=null){

           if(autherAndForward.toString().equals(AutherAndForward.Forward.getCode().toString())){
               VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);
               if(videoReq!=null){
                   videoReq.setAutherAndForward(autherAndForward);
                   redisTemplate.opsForHash().put(user.getUserId(), videoPath,videoReq);
                   return new BaseResult(1,"修改原创成功！");
               }
           }
       }
       return new BaseResult(0,"修改失败！");
    }

    /**
     * 提交表单，插入数据库
     * @param viCreatetime
     * @param videoPath
     * @return
     */
    @Override
    public BaseResult insertVideoToDataBase(User user, String videoPath, Date viCreatetime) {

        VideoReq videoReq = (VideoReq) redisTemplate.opsForHash().get(user.getUserId(), videoPath);

        if(videoReq!=null) {

            if(videoReq.getQuesTitle()!=null && videoReq.getQuesTitle()!=""){
                Question question = new Question(null, videoReq.getQuesTitle(), videoReq.getQuesInfo(),videoReq.getOpusTap(),null,videoReq.getViUrl(),0,videoReq.getUserId(),videoReq.getViUserName(),videoReq.getViUserImg(),videoReq.getViCreatetime(),0);
                Question save1 = questionRepository.save(question);
            }

            videoReq.setViCreatetime(viCreatetime);
            Video video = new Video(null, videoReq.getViTitle(), videoReq.getViUrl(), videoReq.getViImg(), videoReq.getViSize(), videoReq.getViLength(), videoReq.getViCreatetime(), videoReq.getViInfo(), 0, 0, videoReq.getUserId(), null, videoReq.getOpusTap(), 0, videoReq.getViUserName(), videoReq.getViUserImg(), videoReq.getAutherAndForward());
            Video save = videoRepository.save(video);

            List<TypeTemp> typeTempArrayList = new ArrayList<>();
            while (videoReq.getTypesList().iterator().hasNext()) {
                Type type = videoReq.getTypesList().iterator().next();
                TypeTemp typeTemp = new TypeTemp(null, save.getVideoId(), save.getOpusTap(), type.getTypeId());
                TypeTemp save2 = typeTempRepository.save(typeTemp);
                typeTempArrayList.add(save2);
            }

            if(save!=null && typeTempArrayList.size()>0){

                redisTemplate.opsForHash().delete(user.getUserId(), videoPath);
                return new BaseResult(1,"发布成功！");
            }
        }
        return new BaseResult(0,"发布失败！");
    }

    /**
     *将用户看过的视频放入浏览记录
     * @param videoId 视频id
     */
    @Override
    public BaseResult recordViewHistory(User user, Integer videoId) {

        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), "video");
        if(!aBoolean){
            ArrayList<Video> videoArrayList = new ArrayList<>();
        }

        Video video = videoRepository.findById(videoId).get();
        //播放次数加一
        video.setViPlaynum(video.getViPlaynum()+1);
        Video video1 = videoRepository.saveAndFlush(video);
        VideoReq videoReq = new VideoReq();
        BeanUtils.copyProperties(video1,videoReq);

        //将此视频的信息和标签放入redis浏览记录
        List<Type> list = videoMapper.findVideoType(videoId);
        videoReq.setTypesList(list);
        ArrayList<VideoReq> videoArrayList = (ArrayList<VideoReq>) redisTemplate.opsForHash().get(user.getUserId(), "video");
        if(!videoArrayList.contains(videoReq)){
            videoArrayList.add(videoReq);
        }
        return new BaseResult(1,"记录成功！");
    }

    /**
     * 根据用户的浏览记录和喜好从而向用户推荐视频
     * @return 推荐的视频结果集
     */
    @Override
    public BaseResult recommendVideos(User user) {

        Boolean aBoolean = redisTemplate.opsForHash().hasKey(user.getUserId(), "video");
        //用户第一次播放视频，无播放记录，因此全部推荐
        if(!aBoolean){
            List<Video> videoList = videoRepository.findAll();
            return new BaseResult(1,"用户第一次看视频查询成功！",videoList);
        }
        //用户第二次播放视频，存在播放记录，按照点赞、浏览两级进行推荐视频
        //目标的喜欢视频集合
        List<VideoReq> videosList = new ArrayList<>();

        //喜欢的视频的结果集
        List<LikeOpus> all = likeOpusRepository.findAll();
        while (all.iterator().hasNext()){
            //获取喜欢的视频对象
            LikeOpus next = all.iterator().next();
            if((next.getLikeStatus()==1) && (next.getLikedPostId().equals(user.getUserId().toString())) && (next.getFollowOpusTap().equals("3")) ){
                //获取喜欢的视频id
                int videoId = Integer.parseInt(next.getFollowOpusId());
                //获得喜欢的视频标签结果集
                List<Type> videoTypeList = videoMapper.findVideoType(videoId);
                while(videoTypeList.iterator().hasNext()){
                    Type type = videoTypeList.iterator().next();
                    List<VideoReq> videosList1 = videoMapper.findTypeVideos(type.getTypeId());
                    //根据标签集合拿到相关视频集合
                    while(videosList1.iterator().hasNext()){
                        VideoReq videoReq1 = videosList1.iterator().next();
                        //判断返回前端的目标视频集合是否存在此视频，不存在的话，添加视频
                        while(!videosList.contains(videoReq1)){
                            videosList.add(videoReq1);
                        }
                    }
                }
            }
        }

        //浏览全部视频集
        ArrayList<VideoReq> videoArrayList = (ArrayList<VideoReq>) redisTemplate.opsForHash().get(user.getUserId(), "video");
        //遍历浏览视频集合
        while(videoArrayList.iterator().hasNext()){
            VideoReq videoReq = videoArrayList.iterator().next();
            if(videoReq!=null){
                List<Type> typesList = videoReq.getTypesList();
                //获得标签集合
                while(typesList.iterator().hasNext()){
                    Type type = typesList.iterator().next();
                    List<VideoReq> videosList2 = videoMapper.findTypeVideos(type.getTypeId());
                        //根据标签集合拿到相关视频集合
                        while(videosList2.iterator().hasNext()){
                            VideoReq videoReq2 = videosList2.iterator().next();
                            //判断返回前端的目标视频集合是否存在此视频，不存在的话，添加视频
                            while(!videosList.contains(videoReq2)){
                                    videosList.add(videoReq2);
                            }
                        }
                    }
                }
            }
        return new BaseResult(1,"推荐成功！",videosList);
    }

    /**
     * 展示具体的某一个视频
     * @param videoId 视频id
     * @return  视频详情结果集
     */
    @Override
    public BaseResult findVideoByVideoId(Integer videoId) {

        //拿到视频的对象
        Video video = videoRepository.findById(videoId).get();
        if(video!=null){
            //拿到标签的结果集
            List<Type> videoTypeList = videoMapper.findVideoType(videoId);
            //带标签结果集的对象
            VideoReq videoReq = new VideoReq();
            BeanUtils.copyProperties(video,videoReq);
            videoReq.setTypesList(videoTypeList);
            return new BaseResult(1,"查询成功！",videoReq);
        }
        return new BaseResult(0,"查询失败！");
    }

    /**
     * 展示用户发的视频
     * @return  视频结果集
     */
    @Override
    public BaseResult findVideoByUserId(User user) {

        List<VideoReq> list = videoMapper.findVideoByUserId(user.getUserId());
        if(list!=null && list.size()>0){
            return new BaseResult(1,"查询成功！",list);
        }
        return new BaseResult(0,"查询失败！");
    }


    //私有方法，从路径拿到视频，截图保存在本地的方法
    private static FileItem createFileItem(String filePath)
    {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "textField";
        int num = filePath.lastIndexOf(".");
        String extFile = filePath.substring(num);
        FileItem item = factory.createItem(textFieldName, "text/plain", true,
                "MyFileName" + extFile);
        File newfile = new File(filePath);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try
        {
            FileInputStream fis = new FileInputStream(newfile);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192))
                    != -1)
            {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return item;
    }
}
